package com.ray.service;

import static org.junit.Assert.assertNotNull;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.ManagedArray;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.google.appengine.api.search.query.QueryParser.andOp_return;
import com.ray.bean.CombinationKeyBean;
import com.ray.bean.CombinationKeyBean.Procedure;
import com.ray.bean.CompanyMaterialTableBean;
import com.ray.bean.DatatablesViewPageBean;
import com.ray.bean.OrderBean;
import com.ray.bean.ProcessBean;
import com.ray.bean.QueryOrderPageBean;
import com.ray.bean.ReportBean;
import com.ray.bean.WorkshopProductionCycleBean;
import com.ray.mapper.PartsProcedureMapper;
import com.ray.util.ReturnStringUtil;
import com.ray.util.StringUtil;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * 配件工艺工序
 * @author natelu
 *
 */
@Service
public class PartsProcedureService {
	
	@Autowired
	PartsProcedureMapper partsProcedureMapper;
	@Autowired
	OrderService orderService;
	@Autowired
	FileManagerService fileManagerService;
	@Autowired
	BasicDataService basicDataService;

	/**
	 * 从订单明细中获取物料类型，从公司物料表中获取对应的物料名称和材质
     * 获取(物料类型，物料名称，物料材质都有)的公司物料
     * @param loginCompany(公司)
     * @author natelu
     * @return
     */
	public List<CombinationKeyBean> getCompanyMaterial(Map map) {
		return partsProcedureMapper.getCompanyMaterial(map);
	}

	/**
	  * 获取组合物料工序
	  * @param loginCompany(公司)
	  * @author natelu
	  * @return
	  */
	public DatatablesViewPageBean getMaterialProcedure(Map map) {
	    int count=0;
	    List<CombinationKeyBean> combinationKeyList=partsProcedureMapper.getCombinationKey(map);
	    count=partsProcedureMapper.getCombinationKeyCount(map);
	    map.put("combinationKeyList", combinationKeyList);
	    combinationKeyList=partsProcedureMapper.getMaterialProcedure(map);
		DatatablesViewPageBean<CombinationKeyBean> materialProcedure=new DatatablesViewPageBean<CombinationKeyBean>();
		materialProcedure.setiTotalDisplayRecords(count);
		materialProcedure.setiTotalRecords(count);
		materialProcedure.setReturnData(combinationKeyList);
		return materialProcedure;
	}

	
	/**
	  * 获取部门下的工序
	  * @param loginCompany(公司)
	  * @param deptId(部门id)
	  * @param searchWhere(查询条件)
	  * @author natelu
	  * @return
	  */
	public List<ProcessBean> getDeptProcedure(Map map) {
		return partsProcedureMapper.getDeptProcedure(map);
	}

	
	/**
	  * 添加新组合
	  * @param materialType(物料类型)
	  * @param materialName(物料名称 可为空)
	  * @param materialQuality(材质  可为空)
	  * @param arts(工艺  可为空)
	  * @param deptId(部门id)
	  * @param procedureArray(工序json数组)
	  * @author natelu
	  * @return
	  */
	public void addCombination(Map map) {
		 Assert.notNull(map.get("materialType"), "未获取到物料类型");
//		 Assert.notNull(map.get("materialName"), "未获取到物料名称");
//		 Assert.notNull(map.get("materialQuality"), "未获取到材质");
		 Assert.notNull(map.get("arts"), "未获取到工艺");
		 Assert.notNull(map.get("deptId"), "未获取到部门");
		 Assert.notNull(map.get("procedureArray"), "未获取到工序json字符串");
		 String procedureArray=map.get("procedureArray").toString();//工序json字符串
		 JSONArray jsonArray = JSONArray.fromObject(procedureArray);//把String转换为 数组 
		 List<ProcessBean> list= (List<ProcessBean>)JSONArray.toCollection(jsonArray, ProcessBean.class);
		 Assert.isTrue(list!=null && list.size()>0,"请选择工序");
		 String combinationKey=StringUtil.getUUID();//组合键
		 Assert.isTrue(checkCombination(map),"此物料组合已存在");
		 map.put("id", combinationKey);		
		 partsProcedureMapper.addCombination(map);
		 map.put("processList", list);
		 partsProcedureMapper.addCombinationProcedure(map);
	}

	
	 /**
	  * 通过工序另寻为添加新组合
	  * @param materialType(物料类型)
	  * @param materialName(物料名称 可为空)
	  * @param materialQuality(材质  可为空)
	  * @param arts(工艺  可为空)
	  * @param beforeId(之前组合id)
	  * @author natelu
	  * @return
	  */
	public void saveOtherCombination(Map map) {
		 Assert.notNull(map.get("materialType"), "未获取到物料类型");
//		 Assert.notNull(map.get("materialName"), "未获取到物料名称");
//		 Assert.notNull(map.get("materialQuality"), "未获取到材质");
		 Assert.notNull(map.get("arts"), "未获取到工艺");
		 Assert.notNull(map.get("beforeId"), "未获取到原组合id");
		 Assert.isTrue(checkCombination(map),"此物料组合已存在");
		 Map newMap=new HashMap();
		 newMap.put("id", map.get("beforeId"));
		 CombinationKeyBean combinationKeyBean =partsProcedureMapper.getCombinationKeyById(newMap);
		 Assert.notNull(combinationKeyBean,"保存之前的组合不存在");
		 map.put("deptId", combinationKeyBean.getDeptId());
		 map.put("id", StringUtil.getUUID());
		 partsProcedureMapper.addCombination(map);
		 partsProcedureMapper.saveOtherCombinationProcedure(map);
	}

	/**
	  * 校验组合是否存在
	  * @param loginCompany(物料类型)
	  * @param materialType(物料类型)
	  * @param materialName(物料名称)
	  * @param materialQuality(材质)
	  * @param arts(工艺)
	  * @param deptId(部门id)
	  * @author natelu
	  * @return
	  */
	private boolean checkCombination(Map map) {
		boolean bool=false;
		List<CombinationKeyBean> combinationKeyBeanList=partsProcedureMapper.checkCombination(map);
		if(combinationKeyBeanList==null || combinationKeyBeanList.size()<=0) {
			bool=true;
		}
		return bool;
	}

	
	 /**
	  * 删除组合
	  * @param id
	  * @author natelu
	  * @return
	  */
	public void deleteCombination(Map map) {
		Assert.notNull(map.get("id"),"未获取到id");
		partsProcedureMapper.deleteCombination(map);
		partsProcedureMapper.deleteCombinationProcedure(map);//删除之前工序
	}
	
	
	/**
	 * 删除多物料组合
	 * @param id
	 * @author natelu
	 * @return
	 */
	public void deleteManyMaterialGroup(Map map) {
		Assert.notNull(map.get("id"),"未获取到id");
		partsProcedureMapper.deleteManyMaterialGroup(map);
		partsProcedureMapper.deleteCombinationProcedure(map);//删除之前工序
	}

	 /**
	  * 获取组合键下有的和没有的工序
	  * @param id(公司)
	  * @author natelu
	  * @return
	  */
	public Map getMaterialHaveAndNoHaveProcedure(Map map) {
		Assert.notNull(map.get("id"), "未获取到id");
		CombinationKeyBean combinationKey=partsProcedureMapper.getCombinationKeyById(map);
		Assert.notNull(combinationKey, "此组合不存在");
		List<ProcessBean> processListHave=partsProcedureMapper.getCombinationHave(map);
		map.put("deptId", combinationKey.getDeptId());
		List<ProcessBean> processListNoHave=partsProcedureMapper.getCombinationNoHave(map);
		Map returnMap=new HashMap();
		returnMap.put("combinationKey", combinationKey);
		returnMap.put("processListHave", processListHave);
		returnMap.put("processListNoHave", processListNoHave);
		return returnMap;
	}
	
	
	/**
	 * 获取多物料组合键下有的和没有的工序
	 * @param id(公司)
	 * @author natelu
	 * @return
	 */
	public Map getManyMaterialHaveAndNoHaveProcedure(Map map) {
		Assert.notNull(map.get("id"), "未获取到id");
		CombinationKeyBean combinationKey=partsProcedureMapper.getManyMaterialById(map);
		Assert.notNull(combinationKey, "此组合不存在");
		List<ProcessBean> processListHave=partsProcedureMapper.getCombinationHave(map);
		map.put("deptId", combinationKey.getDeptId());
		List<ProcessBean> processListNoHave=partsProcedureMapper.getCombinationNoHave(map);
		Map returnMap=new HashMap();
		returnMap.put("combinationKey", combinationKey);
		returnMap.put("processListHave", processListHave);
		returnMap.put("processListNoHave", processListNoHave);
		return returnMap;
	}

	
	 /**
	  * 获取组合键下有的和没有的物料组合
	  * @param id
	  * @author natelu
	  * @return
	  */
	public Map getGroupHaveAndNoHaveMaterial(Map map) {
		Assert.notNull(map.get("id"), "未获取到id");
		CombinationKeyBean combinationKey=partsProcedureMapper.getManyMaterialById(map);
		Assert.notNull(combinationKey, "此组合不存在");
		List<CompanyMaterialTableBean> haveMaterialList=partsProcedureMapper.getMaterialDateilByIdArray(combinationKey.getGruopId().split("-"));
		map.put("idArray", combinationKey.getGruopId().split("-"));
		List<CompanyMaterialTableBean> noHaveMaterialList=partsProcedureMapper.getNoHaveMaterialListByIdArray(map);
		Map returnMap=new HashMap();
		returnMap.put("haveMaterialList", haveMaterialList);
		returnMap.put("noHaveMaterialList", noHaveMaterialList);
		return returnMap;
	}
	/**
	  * 设置组合工序
	  * @param id(组合id)
	  * @param procedureArray(工序id)
	  * @author natelu
	  * @return
	  */
	public void setCombinationProcrdure(Map map) {
        Assert.notNull(map.get("id"), "未获取到组合id");		
        Assert.notNull(map.get("procedureArray"), "未获取到工序集合");	
        CombinationKeyBean combinationKey=partsProcedureMapper.getCombinationKeyById(map);
        Assert.notNull(combinationKey, "此组合不存在");
        String procedureArray=map.get("procedureArray").toString();//工序json字符串
		JSONArray jsonArray = JSONArray.fromObject(procedureArray);//把String转换为 数组 
		List<ProcessBean> list= (List<ProcessBean>)JSONArray.toCollection(jsonArray, ProcessBean.class);
		Assert.isTrue(list!=null && list.size()>0,"如要移除所有工序，请删除此组合");
		partsProcedureMapper.deleteCombinationProcedure(map);//删除之前工序
		map.put("processList", list);
		partsProcedureMapper.addCombinationProcedure(map);
	}
	
	
	/**
	 * 多物料
	 * @param id(组合id)
	 * @param procedureArray(工序id)
	 * @author natelu
	 * @return
	 */
	public void setManymaterialProcrdure(Map map) {
		Assert.notNull(map.get("id"), "未获取到组合id");		
		Assert.notNull(map.get("procedureArray"), "未获取到工序集合");	
		CombinationKeyBean combinationKey=partsProcedureMapper.getManyMaterialById(map);
		Assert.notNull(combinationKey, "此组合不存在");
		String procedureArray=map.get("procedureArray").toString();//工序json字符串
		JSONArray jsonArray = JSONArray.fromObject(procedureArray);//把String转换为 数组 
		List<ProcessBean> list= (List<ProcessBean>)JSONArray.toCollection(jsonArray, ProcessBean.class);
		Assert.isTrue(list!=null && list.size()>0,"如要移除所有工序，请删除此组合");
		partsProcedureMapper.deleteCombinationProcedure(map);//删除之前工序
		map.put("processList", list);
		partsProcedureMapper.addCombinationProcedure(map);
	}

	 /**
	  * 获取组个没有的工序
	  * @param id(组合id)
	  * @param deptId(部门id)
	  * @author natelu
	  * @return
	  */
	public List<ProcessBean> getCombinationNoHaveProcrdere(Map map) {
		Assert.notNull(map.get("id"), "未获取到组合id");		
		Assert.notNull(map.get("deptId"), "未获取到部门id");		
		return partsProcedureMapper.getCombinationNoHave(map);
	}

	
	/**
	  * 设置工序加工对象
	  * @param maching(加工对象)
	  * @param materialName(物料名称)
	  * @param materialQuality(材质)
	  * @param arts(工艺)
	  * @param combinationId(组合id)
	  * @param procedureId(工序id)
	  * @author natelu
	  * @return
	  */
	public void setProcedureMaching(Map map) {
		Assert.notNull(map.get("combinationId"), "未获取到组合id");		
		Assert.notNull(map.get("procedureId"), "未获取到工序id");
		Assert.notNull(map.get("maching"), "未获取到加工对象");
		partsProcedureMapper.setProcedureMaching(map);
	}

	/**
	  * 设置组合顺序
	  * @param id(组合id)
	  * @param firstSort(第一顺序)
	  * @param secondSort(第二顺序)
	  * @param thirdSort(第三顺序)
	  * @author natelu
	  * @return
	  */
	public void setCombinationSort(Map map) {
		Assert.notNull(map.get("id"),"未获取到组合id");
		partsProcedureMapper.setCombinationSort(map);
	}

	/**
	  * 获取订单物料组合工序
	  * @param orderId(订单编号)
	  * @param sort(排序字段)
	  * @author natelu
	  * @return
	  */
	public Map  getOrderMaterialProcedure(Map map) {
		Map returnMap=new HashMap();
		Assert.notNull(map.get("orderId"),"未获取到订单编号");
		Assert.notNull(map.get("sort"),"排序字段");
		
		OrderBean orderBean=partsProcedureMapper.getOrderByManyWhere(map);
		Assert.isTrue(orderBean!=null && !"".equals(orderBean.getOrderId()),"此订单不存在");
		map.put("orderId", orderBean.getOrderId());
		//获取订单的物料类型
		List<CombinationKeyBean> orderMaterialList=partsProcedureMapper.getOrderMaterialList(map);
		Assert.isTrue(orderMaterialList!=null && orderMaterialList.size()>0,"此订单无物料");
		
		map.put("orderMaterialList", orderMaterialList);
		map.put("orderCount", orderBean.getOrderCount());
        //获取同物料类型的设置
		List<CombinationKeyBean> list=partsProcedureMapper.getOrderMaterialProcedure(map);
		Assert.isTrue(list!=null && list.size()>0,"没有匹配此订单物料的工序");
		list=this.getMateMaterialType(orderMaterialList,list);
		if(!"defaultSort".equals(map.get("sort"))) {
			Collections.sort(list, Comparator.comparing(CombinationKeyBean::getFirstSort));
		}
		if(list!=null && list.size()>=0) {
			List<CombinationKeyBean> groupList=this.getManyMaterialProcedureByGroupIdList(list,map);
			if(groupList!=null && groupList.size()>0) {
				groupList=this.getMateMaterialTypeGroup(orderMaterialList,groupList);
				list.addAll(groupList);
			}
		}
		returnMap.put("combinationList", list);
		returnMap.put("orderId", orderBean.getOrderId());
		return returnMap;
	}

	
	/**
	 * 整理匹配的物料
	 * @param orderMaterialList(订单物料)
	 * @param combinationList(设置物料)
	 * @return
	 */
	private List<CombinationKeyBean> getMateMaterialType(List<CombinationKeyBean> orderMaterialList,
			List<CombinationKeyBean> combinationList) {
		List<CombinationKeyBean> returnList=new ArrayList<CombinationKeyBean>();
		//循环遍历订单物料
		for(CombinationKeyBean order:orderMaterialList) {
			List<CombinationKeyBean> filterList=new ArrayList<CombinationKeyBean>();
//			List<CombinationKeyBean> oneList=new ArrayList<CombinationKeyBean>();
			
			//先过滤物料类型和工艺
			filterList=combinationList.stream().filter(combination -> combination.getArts().equals(order.getArts()) && combination.getMaterialType().equals(order.getMaterialType()) ).collect(Collectors.toList());
			//如果不存在，只过滤物料类型
		    if(filterList.size()==1) {
		    	returnList.add(filterList.get(0));
				continue;
		    }
		    //得到匹配一项的
			if(filterList.size()<=0) {
				filterList=combinationList.stream().filter(combination ->  combination.getMaterialType().equals(order.getMaterialType()) &&  combination.getArts().equals("")).collect(Collectors.toList());
				if(filterList.size()==1) {
			    	returnList.add(filterList.get(0));
					continue;
			    }
			}
			//都没有，直接返回
			order.setId("");
			order.setFirstSort("1001");
			returnList.add(order);
		}
		return returnList;
	}
	
	/**
	 * 分组数据取工序
	 * @param orderMaterialList
	 * @param combinationList
	 * @return
	 */
	private List<CombinationKeyBean> getMateMaterialTypeGroup(List<CombinationKeyBean> orderMaterialList,
			List<CombinationKeyBean> combinationList) {
		
		for(CombinationKeyBean group:combinationList) {
			List<Procedure> groupProcedureList=group.getProcedureList();
			//未设置加工对象的工序
			List<Procedure> setProcedureList=groupProcedureList.stream().filter(pp->"".equals(pp.getOtherMaching())).collect(Collectors.toList());
			for(int i=0;i<orderMaterialList.size();i++) {
				CombinationKeyBean material=orderMaterialList.get(i);
				List<Procedure> filterList=groupProcedureList.stream().filter(pp->pp.getOtherMaching().equals(material.getMaterialType()) && pp.getArts().equals(material.getArts())).collect(Collectors.toList());
				if(filterList.size()<=0) {
					filterList=groupProcedureList.stream().filter(pp->pp.getOtherMaching().equals(material.getMaterialType()) && pp.getArts().equals("")).collect(Collectors.toList());
				}
				setProcedureList.addAll(filterList);
			}
			Collections.sort(setProcedureList, Comparator.comparing(Procedure::getSort));
			group.setProcedureList(setProcedureList);
		}
		return combinationList;
	}

	/**
	 * 获取多物料组合工序
	 * @param list
	 * @return
	 */
//	 private List<CombinationKeyBean> getManyMaterialProcedureByGroupIdList(List<CombinationKeyBean> list) {
//		 Set<String> materialIdSet=new TreeSet<String>();
//		 for(CombinationKeyBean combinationKeyBean:list) {
//			 if(combinationKeyBean.getId()!=null && !combinationKeyBean.getId().equals("")) {
//				 materialIdSet.add(combinationKeyBean.getId());
//			 }
//		 }
//		 if(materialIdSet.size()>=2) {
//			 List<CombinationKeyBean> returnList=new ArrayList<CombinationKeyBean>();
//			 List<String> groupIdList=StringUtil.groupStr(materialIdSet, new ArrayList<String>());
//				 for(int i=0;i<groupIdList.size();i=i+2000) {
//					 List<String> subList=new ArrayList<String>();
//					 if(i+2000>=groupIdList.size()) {
//						 subList=groupIdList.subList(i, groupIdList.size());
//						 returnList.addAll(partsProcedureMapper.getManyMaterialProcedureByGroupIdList(subList));
//						 break;
//					 }else {
//						 subList=groupIdList.subList(i, i+1999);
//						 returnList.addAll(partsProcedureMapper.getManyMaterialProcedureByGroupIdList(subList));
//					 }
//				 }
//			 return returnList;
//		 }else {return null;}
//	}
	 
	 
	 /**
	  * 获取多物料组合工序
	  * @param list
	  * @param map 
	  * @return
	  */
	 private List<CombinationKeyBean> getManyMaterialProcedureByGroupIdList(List<CombinationKeyBean> list, Map map) {
		 Set<String> materialIdSet=new TreeSet<String>();
		 for(CombinationKeyBean combinationKeyBean:list) {
			 if(combinationKeyBean.getId()!=null && !combinationKeyBean.getId().equals("")) {
				 materialIdSet.add(combinationKeyBean.getId());
			 }
		 }
		 if(materialIdSet.size()>=2) {
			 List<String> companyGroupIdList=partsProcedureMapper.getCompanyGroupId(map);
			 if(companyGroupIdList!=null && companyGroupIdList.size()>0) {
				 Set<String> companySet=new TreeSet<String>();
				 for(String str:companyGroupIdList) {
					 String[] xx=str.split("-");
					 companySet.addAll(Arrays.asList(xx));
				 }
				 materialIdSet.retainAll(companySet);
				 List<String> groupIdList=StringUtil.groupStr(materialIdSet, new ArrayList<String>());
				 //获取所有公司物料组合
				 groupIdList.retainAll(companyGroupIdList);
				 if(groupIdList.size()>0) {
					 map.put("groupIdList", groupIdList);
					 return partsProcedureMapper.getManyMaterialProcedureByGroupIdList(map);
				 }else {
					 return null;
				 }
				 
			 }else {
				 return null;
			 }
		 }else {return null;}
	 }

	/**
	  * 保存订单工序
	  * @param orderId(订单编号)
	  * @param procedureArray(工序集合)
	  * @author natelu
	  * @return
	  */
	public void saveOrderMaterialProcedure(Map map) {
		Assert.notNull(map.get("orderId"),"未获取到订单编号");
		Assert.notNull(map.get("procedureArray"),"未获取到工序集合");
		List<String> strList=partsProcedureMapper.getAleradyOrderByOrderId(map);
		Assert.isTrue(strList==null || strList.size()<=0,"此订单已保存过");
		String procedureArray=map.get("procedureArray").toString();//工序json字符串
		JSONArray jsonArray = JSONArray.fromObject(procedureArray);//把String转换为 数组 
		List<ProcessBean> list= (List<ProcessBean>)JSONArray.toCollection(jsonArray, ProcessBean.class);
		Assert.isTrue(list!=null && list.size()>0,"没有配置工序");
		map.put("processList", list);
		partsProcedureMapper.saveOrderMaterialProcedure(map);
	}

	 /**
	  * 获取已保存的订单物料工序
	  * @param orderId(订单编号)
	  * @author natelu
	  * @return
	  */
	public List<CombinationKeyBean> getAlreadySaveProcedure(Map map) {
		Assert.notNull(map.get("orderId"),"未获取到订单编号");
		return partsProcedureMapper.getAlreadySaveProcedure(map);
	}

	 /**
	  * 获取已保存的物料
	  * @param loginCompany(登录人公司)
	  * @param serachWhere(查询条件)
	  * @author natelu
	  * @return
	  */
	public List<CombinationKeyBean> getOneMaterial(Map map) {
		return partsProcedureMapper.getOneMaterial(map);
	}

	
	 /**
	  * 保存多物料组合工序
	  * @param idArray(物料组合id)
	  * @param procedureArray(工序id,序号)
	  * @param deptId(部门id)
	  * @author natelu
	  * @return
	  */
	public void addManyMaterial(Map map) {
		 Assert.notNull(map.get("idArray"),"未获取到物料集合");
		 Assert.notNull(map.get("procedureArray"),"未获取到工序集合");
		 //获取工序集合
		 String procedureArray=map.get("procedureArray").toString();//工序json字符串
		 JSONArray jsonArray = JSONArray.fromObject(procedureArray);//把String转换为 数组 
		 List<ProcessBean> list= (List<ProcessBean>)JSONArray.toCollection(jsonArray, ProcessBean.class);
		 
		 //获取物料组合id集合
		 String idArray=map.get("idArray").toString();//工序json字符串
		 JSONArray idArrayJson = JSONArray.fromObject(idArray);//把String转换为 数组 
		 List<String> idList=idArrayJson.subList(0, idArrayJson.size());
		 Set<String> materialIdSet=new TreeSet<String>(idList);
		 Assert.isTrue(materialIdSet.size()>=2,"至少选择两种物料");
		 StringBuilder sb=new StringBuilder();;
		 for(String str:materialIdSet) {
			 sb.append(str).append("-");
		 }
		 String groupId=sb.toString().substring(0, sb.toString().length()-1);
		 Assert.isTrue(checkMaterialGroup(groupId),"该组合已存在");
		 map.put("id", StringUtil.getUUID());
		 map.put("groupId", groupId);
		 partsProcedureMapper.addManyMaterial(map);
		 map.put("processList", list);
		 partsProcedureMapper.addCombinationProcedure(map);
	}
	
	
	 /**
	  * 组合物料工序另存为
	  * @param idArray(物料组合id)
	  * @param beforeId(保存之前的id)
	  * @author natelu
	  * @return
	  */
	public void updateGroupId(Map map) {
		Assert.notNull(map.get("idArray"),"未获取到物料集合");
		Assert.notNull(map.get("beforeId"),"保存之前的组合id");
		
		//获取物料组合id集合
		String idArray=map.get("idArray").toString();//工序json字符串
		JSONArray idArrayJson = JSONArray.fromObject(idArray);//把String转换为 数组 
		List<String> idList=idArrayJson.subList(0, idArrayJson.size());
		Set<String> materialIdSet=new TreeSet<String>(idList);
		Assert.isTrue(materialIdSet.size()>=2,"至少选择两种物料");
		StringBuilder sb=new StringBuilder();;
		for(String str:materialIdSet) {
			sb.append(str).append("-");
		}
		String groupId=sb.toString().substring(0, sb.toString().length()-1);
		Assert.isTrue(checkMaterialGroup(groupId),"该组合已存在");
		map.put("groupId", groupId);
		Map newMap=new HashMap();
		newMap.put("id", map.get("beforeId"));
	    CombinationKeyBean combinationKeyBean =partsProcedureMapper.getManyMaterialById(newMap);
		Assert.notNull(combinationKeyBean,"保存之前的组合不存在");
	    map.put("deptId", combinationKeyBean.getDeptId());
	    map.put("id", StringUtil.getUUID());
		partsProcedureMapper.addManyMaterial(map);
		partsProcedureMapper.saveOtherCombinationProcedure(map);
	}

	/**
	 * 校验组合是否已存在
	 * @param groupId
	 * @return
	 */
	private boolean checkMaterialGroup(String groupId) {
		boolean bool=false;
		CombinationKeyBean combinationKeyBean=partsProcedureMapper.getMaterialGroupByGroupId(groupId);
		if(combinationKeyBean ==null) {
			bool=true;
		}
		return bool;
	}

	/**
	 * 查找组合物料工序
	 * @param map
	 * @return
	 */
	public DatatablesViewPageBean getManyMaterialProcedure(Map map) {
		
		//获取查询多个物料组合所需要id
		if((map.get("materialType") !=null && !"".equals(map.get("materialType").toString())) || (map.get("arts") !=null && !"".equals(map.get("arts").toString()))) {
			List<String> comIdList=partsProcedureMapper.getManyNeedId(map);
			map.put("comIdList", comIdList);
		}
		
		
		
		
		
		DatatablesViewPageBean<CombinationKeyBean> dvpb=new DatatablesViewPageBean<CombinationKeyBean>();
		List<String> idList=partsProcedureMapper.getGruopIdList(map);
		int count=0;
		List<CombinationKeyBean> returnList=new ArrayList<CombinationKeyBean>();
		if(idList.size()>0) {
			map.put("idList", idList);
			count=partsProcedureMapper.getManyMaterialProcedureCount(map);
			returnList=partsProcedureMapper.getManyMaterialProcedure(map);
			for(CombinationKeyBean combinationKeyBean:returnList) {
				String groupId=combinationKeyBean.getGruopId();
				String[] idArray=groupId.split("-");
				combinationKeyBean.setMaterialList(partsProcedureMapper.getMaterialDateilByIdArray(idArray));
			}
		}
		dvpb.setiTotalDisplayRecords(count);
		dvpb.setiTotalRecords(count);
		dvpb.setReturnData(returnList);
		return dvpb;
	}

	

	
	/**
	  * 获取订单物料
	  * @param orderId(订单编号)
	  * @author natelu
	  * @return
	  */
	public List<CombinationKeyBean> getOrderMaterial(Map map) {
		List<CombinationKeyBean> list=partsProcedureMapper.getAlreadySaveProcedure(map);
		Assert.isTrue(list!=null && list.size()>0,"该订单没有保存工序记录");
		list=partsProcedureMapper.getOrderMaterialList(map);
		return list;
	}

	
	 /**
	  * 获取订单保存的物料类型有的和没有的
	  * @param orderId(订单编号)
	  * @param materialType(物料类型)
	  * @author natelu
	  * @return
	  */
	public Map getOrderMaterialProcedureHaveAndNoHave(Map map) {
		Map returnMap=new HashMap<>();
		String deptId="";
		int materialSort=0;
		List<ProcessBean> processListHave=partsProcedureMapper.getMaterialProcedureHave(map);
		if(processListHave!=null && processListHave.size()>0) {
			deptId=processListHave.get(0).getProductionLine();
			materialSort=processListHave.get(0).getMaterialSort();
		}else {
			OrderBean orderBean=partsProcedureMapper.getOrder(map);
			deptId=orderBean.getDeptId();
		}
		map.put("deptId", deptId);
		List<ProcessBean> processListNoHave=partsProcedureMapper.getMaterialProcedureNoHave(map);
		returnMap.put("deptId", deptId);
		returnMap.put("processListHave", processListHave);
		returnMap.put("processListNoHave", processListNoHave);
		returnMap.put("materialSort", materialSort);
		return returnMap;
	}

	
	 /**
	  * 获取订单物料中没有的工序
	  * @param orderId(订单编号)
	  * @param materialType(物料类型)
	  * @author natelu
	  * @return
	  */
	public List<ProcessBean> getOrderMaterialNoHave(Map map) {
		return partsProcedureMapper.getMaterialProcedureNoHave(map);
	}

	
	 /**
	  * 保存订单工序
	  * @param orderId(订单编号)
	  * @param procedureArray(工序集合)
	  * @param materialType(物料类型)
	  * @author natelu
	  * @return
	  */
	public void saveUpdateProcedure(Map map) {
		Assert.notNull(map.get("orderId"),"未获取到订单编号");
		Assert.notNull(map.get("procedureArray"),"未获取到工序集合");
		String procedureArray=map.get("procedureArray").toString();//工序json字符串
		JSONArray jsonArray = JSONArray.fromObject(procedureArray);//把String转换为 数组 
		List<ProcessBean> list= (List<ProcessBean>)JSONArray.toCollection(jsonArray, ProcessBean.class);
		Assert.isTrue(list!=null && list.size()>0,"请选择物料工序");
		map.put("processList", list);
		partsProcedureMapper.deleteMaterProcedure(map);
		partsProcedureMapper.saveOrderMaterialProcedure(map);
	}

	/**
	  * 获取订单物料采购和入库时间
	  * @param orderId(订单编号)
	  * @author natelu
	  * @return
	  */
	public List<Map> getOrderMaterialParchaseAndInCountTime(Map map) {
		Assert.isTrue(map.get("orderId") != null && !"".equals(map.get("orderId").toString()),"未获取到订单编号");
		return partsProcedureMapper.getOrderMaterialParchaseAndInCountTime(map);
	}

	

	/**
	 * 删除工艺结构树
	 * orderId 订单编号
	 * @param map
	 */
	public void deleteTree(Map map) {
		StringUtil.checkIsTrue(map, "orderId", "未获取到订单编号");
		map.put("type", 8);
		int deleteImg =fileManagerService.deleteImgByOrderIdAndType(map);
		int row=partsProcedureMapper.deleteTree(map);
		Assert.isTrue(row>0,ReturnStringUtil.DELETE_ERROR);
	}
	
	
	/**
	 * 导出为excle
	 * @param map
	 * @param tempFolder
	 * @return
	 */
	public File createExcelFile(Map map, String tempFolder) {
		List<CombinationKeyBean> dataList=this.getAlreadySaveProcedure(map);
		String orderId=map.get("orderId").toString();
		OrderBean orderBean=orderService.getOrderByOrderId(orderId);
		File outFile= new File(tempFolder, UUID.randomUUID().toString() + ".xlsx");
		if(!outFile.getParentFile().exists()){
			outFile.getParentFile().mkdirs();
		}
		Workbook wb;
		OutputStream fos = null;
		
		try {
			wb = new XSSFWorkbook();
			Sheet sheet = wb.createSheet();
			int rowIndex = 0;
			int colIndex=0;
			Row row;
			Cell cell;
			row=sheet.createRow(rowIndex);
			cell = row.createCell(colIndex);
			cell.setCellValue("系统编号:"+orderId);
			colIndex++;
			cell = row.createCell(colIndex);
			cell.setCellValue("工厂型号:"+orderBean.getFactoryId());
			colIndex++;
			cell = row.createCell(colIndex);
			cell.setCellValue("订单编号:"+orderBean.getCompanyOrderId());
			colIndex++;
			cell = row.createCell(colIndex);
			
			
			colIndex=0;
			long sumCount=0;
			for(CombinationKeyBean combinationKeyBean:dataList) {
				rowIndex=1;
				row=sheet.getRow(rowIndex);
				if(row==null) {
					row=sheet.createRow(rowIndex);
				}
				cell = row.createCell(colIndex);
				cell.setCellValue(combinationKeyBean.getMaterialType()+"   "+combinationKeyBean.getProcedureList().size());
				rowIndex++;
				sumCount=sumCount+combinationKeyBean.getProcedureList().size();
				for(Procedure procedure:combinationKeyBean.getProcedureList()) {
					row=sheet.getRow(rowIndex);
					if(row==null) {
						row=sheet.createRow(rowIndex);
					}
					cell = row.createCell(colIndex);
					if("".equals(procedure.getOtherMaching())) {
						cell.setCellValue(procedure.getWorkShopName()+"-"+procedure.getProcedureName());
					}else {
						cell.setCellValue(procedure.getWorkShopName()+"-"+procedure.getProcedureName()+"-"+procedure.getOtherMaching());
					}
					rowIndex++;
				}
				colIndex++;
			}
			rowIndex=0;
			row=sheet.getRow(rowIndex);
			if(row==null) {
				row=sheet.createRow(rowIndex);
			}
			cell = row.createCell(3);
			cell.setCellValue("总工序数："+sumCount);

			fos = new FileOutputStream(outFile);
			wb.write(fos);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != fos)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return outFile;
	}

	
	/**
	  * 配件工序导出为excle
	  * @param searchWhere(是查询还是排序  sort query)
	  * @author natelu
	  * @return
	  * @throws IOException 
	  */
	public File createCombinationKeyPrucedurExcelFile(Map map, String tempFolder) {
		map.put("start", null);
 		map.put("length", null);
 		DatatablesViewPageBean datatablesViewPageBean=this.getMaterialProcedure(map);
 		List<CombinationKeyBean> dataList=datatablesViewPageBean.getReturnData();
 		File outFile= new File(tempFolder, UUID.randomUUID().toString() + ".xlsx");
		if(!outFile.getParentFile().exists()){
			outFile.getParentFile().mkdirs();
		}
		Workbook wb;
		OutputStream fos = null;
		
		try {
			wb = new XSSFWorkbook();
			Sheet sheet = wb.createSheet();
			int rowIndex = 0;
			int colIndex=0;
			Row row;
			Cell cell;
			row=sheet.createRow(rowIndex);
			cell = row.createCell(colIndex);
			cell.setCellValue("组合(物料类型+工艺)");
			colIndex++;
			cell = row.createCell(colIndex);
			cell.setCellValue("工序");
			colIndex++;
			cell = row.createCell(colIndex);
			cell.setCellValue("排序1");
			colIndex++;
			cell = row.createCell(colIndex);
			cell.setCellValue("排序2");
			colIndex++;
			cell = row.createCell(colIndex);
			cell.setCellValue("排序3");
			
			
			rowIndex++;
			long sumCount=0;
			for(CombinationKeyBean combinationKeyBean:dataList) {
				colIndex=0;
				row=sheet.createRow(rowIndex);
				cell = row.createCell(colIndex);
				String groupStr=combinationKeyBean.getMaterialType();
				if(!"".equals(combinationKeyBean.getMaterialName())) {
					groupStr=groupStr+"-"+combinationKeyBean.getMaterialName();
				}
				if(!"".equals(combinationKeyBean.getMaterialQuality())) {
					groupStr=groupStr+"-"+combinationKeyBean.getMaterialQuality();
				}
				if(!"".equals(combinationKeyBean.getArts())) {
					groupStr=groupStr+"+"+combinationKeyBean.getArts();
				}
				cell.setCellValue(groupStr);
				colIndex++;
				cell = row.createCell(colIndex);
				String proStr="";
				for(Procedure procedure:combinationKeyBean.getProcedureList()) {
					String pro="";
					if("".equals(procedure.getOtherMaching())) {
						pro=procedure.getWorkShopName()+"-"+procedure.getProcedureName();
					}else {
						pro=procedure.getWorkShopName()+"-"+procedure.getProcedureName()+"-"+procedure.getOtherMaching();
					}
					proStr=proStr+pro+", ";
				}
				cell.setCellValue(proStr);
				colIndex++;
				cell = row.createCell(colIndex);
				cell.setCellValue(combinationKeyBean.getFirstSort());
				colIndex++;
				cell = row.createCell(colIndex);
				cell.setCellValue(combinationKeyBean.getSecondSort());
				colIndex++;
				cell = row.createCell(colIndex);
				cell.setCellValue(combinationKeyBean.getThirdSort());
				rowIndex++;
			}
			fos = new FileOutputStream(outFile);
			wb.write(fos);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != fos)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return outFile;
	}

	
	 /**
	  * 组合配件工序导出为excle
	  * @author natelu
	  * @return
	  * @throws IOException 
	  */
	public File downlodeManyCombinationKeyPrucedureData(Map map, String tempFolder) {
		map.put("start", null);
 		map.put("length", null);
 		DatatablesViewPageBean datatablesViewPageBean=this.getManyMaterialProcedure(map);
 		List<CombinationKeyBean> dataList=datatablesViewPageBean.getReturnData();
 		File outFile= new File(tempFolder, UUID.randomUUID().toString() + ".xlsx");
		if(!outFile.getParentFile().exists()){
			outFile.getParentFile().mkdirs();
		}
		Workbook wb;
		OutputStream fos = null;
		
		try {
			wb = new XSSFWorkbook();
			Sheet sheet = wb.createSheet();
			int rowIndex = 0;
			int colIndex=0;
			Row row;
			Cell cell;
			row=sheet.createRow(rowIndex);
			cell = row.createCell(colIndex);
			cell.setCellValue("组合(物料类型+工艺)");
			colIndex++;
			cell = row.createCell(colIndex);
			cell.setCellValue("工序");
			
			
			rowIndex++;
			long sumCount=0;
			for(CombinationKeyBean combinationKeyBean:dataList) {
				colIndex=0;
				row=sheet.createRow(rowIndex);
				cell = row.createCell(colIndex);
				List<CompanyMaterialTableBean> listMa=combinationKeyBean.getMaterialList();
				int x=1;
				String manyStr="";
				for(CompanyMaterialTableBean companyMaterialTableBean:listMa) {
					String groupStr=x+"、"+companyMaterialTableBean.getMaterialType();
					if(!"".equals(companyMaterialTableBean.getMaterialName())) {
						groupStr=groupStr+"-"+companyMaterialTableBean.getMaterialName();
					}
					if(!"".equals(companyMaterialTableBean.getMaterial())) {
						groupStr=groupStr+"-"+companyMaterialTableBean.getMaterial();
					}
					if(!"".equals(companyMaterialTableBean.getArts())) {
						groupStr=groupStr+"+"+companyMaterialTableBean.getArts();
					}
					manyStr=manyStr+groupStr+"\r\n";
					x++;
				}
				cell.setCellValue(manyStr);
				colIndex++;
				cell = row.createCell(colIndex);
				String proStr="";
				for(Procedure procedure:combinationKeyBean.getProcedureList()) {
					String pro="";
					if("".equals(procedure.getOtherMaching())) {
						pro=procedure.getWorkShopName()+"-"+procedure.getProcedureName();
					}else {
						pro=procedure.getWorkShopName()+"-"+procedure.getProcedureName()+"-"+procedure.getOtherMaching();
					}
					proStr=proStr+pro+", ";
				}
				cell.setCellValue(proStr);
				rowIndex++;
			}
			fos = new FileOutputStream(outFile);
			wb.write(fos);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != fos)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return outFile;
	}

	/**
	 * 获取工序剩余生产数量
	 * procedureId 工序id
	 * @param map
	 * @return
	 */
	public List<OrderBean> getProcedureSurplusCount(Map map) {
		StringUtil.checkIsTrue(map, "procedureId", "未获取到工序id");
		String processId=map.get("procedureId").toString();
		ProcessBean processBean=basicDataService.getProcessById(processId);
		List<OrderBean> orderBeans=partsProcedureMapper.getProcedureSurplusOrders(map);
		//如果按款计价
		if("款".equals(processBean.getChargeUnit())) {
			orderBeans=orderBeans.stream().filter(order->order.getQuality()==0).collect(Collectors.toList());
		}
		return orderBeans;
	}


}
